package main

import (
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	"path/filepath"
)

var (
	httpPort int
	httpRoot string
)

func parseFlags() {
	flag.IntVar(&httpPort, "port", 8000, "http port")
	flag.StringVar(&httpRoot, "root", ".", "http root")
	flag.Parse()
}

func getLocalIPs() []string {
	ifaces, _ := net.Interfaces()

	var ipList []string
	for _, i := range ifaces {
		addrs, _ := i.Addrs()
		for _, addr := range addrs {
			var ip net.IP
			switch v := addr.(type) {
			case *net.IPNet:
				ip = v.IP
			}
			ipV4 := ip.To4()
			if ipV4 != nil {
				ipList = append(ipList, ipV4.String())
			}
		}
	}

	return ipList
}

func HandlerWithLog(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Printf("%s\t%s\n", r.Method, r.URL.Path)
		h.ServeHTTP(w, r)
	})
}

func main() {
	parseFlags()

	ipList := getLocalIPs()

	rootPath, _ := filepath.Abs(httpRoot)
	fs := http.FileServer(http.Dir(rootPath))
	http.Handle("/", HandlerWithLog(fs))

	log.Printf("serve %v on port: %v\n", rootPath, httpPort)
	log.Printf("can access by\n")
	for _, ip := range ipList {
		log.Printf("\t%s:%d\n", ip, httpPort)
	}
	log.Printf("\n")

	http.ListenAndServe(fmt.Sprintf(":%d", httpPort), nil)
}
